package com.chen.function_demo.chapter2;

/**
 * 第二章第四节
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/11<p>
 * Time: 19:01<p>
 * ================================
 */
public class Section4 {
    /*
        1、什么是闭包：
        比如一个函数对象：y -> x + y
        那么这个函数对象与它的外部变量x形成了闭包（函数对象可以访问外部函数的变量）
        2、闭包的作用：给函数对象提供参数以外的数据。
     */

    /**
     * 模拟函数接口和功能方法
     */
    @FunctionalInterface
    interface Lambda {
        int test(int y);
    }
    static void highOrder(Lambda lambda) {
        System.out.println(lambda.test(1));
    }

    // 静态变量
    static int a = 10;
    // 成员变量
    int b = 11;
    // 参数变量
    void test(int c) {
        // 静态变量
        highOrder(y -> a + y);
        // 成员变量
        highOrder(y -> b + y);
        // 参数变量
        highOrder(y -> c + y);
    }
    // 根据上面的模拟，可以得出结论：静态变量、成员变量、参数变量都可以在函数对象中访问到，和函数对象组成闭包。
    /*
        闭包的限制：闭包所用的外部变量应该是final或者effectively final
        effectively final：虽然没有用final修饰，但是它的行为必须和final修饰的变量一样，不能被修改
        如果是和对象组成闭包，那final只是检查对象不变，但是内部数据可变
     */

    /**
     * 模拟学生类
     */
    static class Student {
        int age;
        public Student(int age) {
            this.age = age;
        }
    }

    public static void main(String[] args) {
        Student student = new Student(18);
        highOrder(y -> student.age + y);
        student.age = 19;
        highOrder(y -> student.age + y);
        //这个例子证明 对象没变 但其实内部类数据改变了
    }
}
